workato-connector-sdk 1.1.0 → 1.2.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 +4 -4
- data/README.md +1 -0
- data/lib/workato/cli/exec_command.rb +30 -10
- data/lib/workato/cli/multi_auth_selected_fallback.rb +33 -0
- data/lib/workato/cli/oauth2_command.rb +50 -12
- data/lib/workato/connector/sdk/connection.rb +83 -15
- data/lib/workato/connector/sdk/connector.rb +6 -4
- data/lib/workato/connector/sdk/dsl/aws.rb +5 -2
- data/lib/workato/connector/sdk/dsl/csv.rb +125 -0
- data/lib/workato/connector/sdk/dsl/execution_context.rb +44 -0
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +8 -1
- data/lib/workato/connector/sdk/dsl.rb +1 -0
- data/lib/workato/connector/sdk/errors.rb +11 -0
- data/lib/workato/connector/sdk/lookup_tables.rb +3 -1
- data/lib/workato/connector/sdk/operation.rb +24 -8
- data/lib/workato/connector/sdk/request.rb +89 -47
- data/lib/workato/connector/sdk/schema.rb +5 -3
- data/lib/workato/connector/sdk/settings.rb +4 -2
- data/lib/workato/connector/sdk/trigger.rb +9 -8
- data/lib/workato/connector/sdk/version.rb +1 -1
- data/lib/workato/connector/sdk.rb +3 -2
- data/lib/workato/extension/case_sensitive_headers.rb +0 -25
- data/lib/workato/extension/content_encoding_decoder.rb +67 -0
- data/lib/workato/extension/extra_chain_cert.rb +0 -14
- data/lib/workato/extension/hash_with_indifferent_access.rb +19 -0
- data/lib/workato/extension/string.rb +2 -1
- data/lib/workato/{connector/sdk → utilities}/xml.rb +4 -4
- metadata +18 -6
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b49034b5762b2b44d0987d72eb74327e379284347b793714149d85d354a5bb57
|
4
|
+
data.tar.gz: 1be17d19381fe42689ef4a157a56eca0fb8c61a9c0e90e981e5a373305ed771f
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5bcc365d25ec713df12b75d9d6d5fb8a6a73266b94cf012829e4a2c98af955f1fcfa7b0d0f7e69861a4ee6cb54af24ed8952bbb590553e93a37fcf2933c69459
|
7
|
+
data.tar.gz: 1da6193b9a1b04e3d3e2c6fb34fcd0eeec7666908c61df5c7ec386381ba8f33207b50b8ffc1e9d581fecb599fc423f84f9f79867120322356aa4d645b9b7da5e
|
data/README.md
CHANGED
@@ -16,6 +16,7 @@ This guide below showcases how you can do the following things:
|
|
16
16
|
2. Choose between Ruby versions `2.4.10` `2.5.X` or `2.7.X`. Our preferred version is `2.7.X`.
|
17
17
|
3. Verify you're running a valid ruby version. Do this by running either `ruby -v` or the commands within your version manager. i.e., `rvm current` if you have installed RVM.
|
18
18
|
4. For Windows you need tzinfo-data gem installed as well. `gem install tzinfo-data`
|
19
|
+
5. SDK depends on `charlock_holmes` gem. Check [gem's documentation](https://github.com/brianmario/charlock_holmes#installing) if you have troubles when install this dependency. Additional [details for Windows](https://github.com/brianmario/charlock_holmes/issues/84#issuecomment-652877605)
|
19
20
|
|
20
21
|
```bash
|
21
22
|
ruby -v
|
@@ -2,11 +2,13 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'thor'
|
5
|
+
require_relative './multi_auth_selected_fallback'
|
5
6
|
|
6
7
|
module Workato
|
7
8
|
module CLI
|
8
9
|
class ExecCommand
|
9
10
|
include Thor::Shell
|
11
|
+
include MultiAuthSelectedFallback
|
10
12
|
|
11
13
|
DebugExceptionError = Class.new(StandardError)
|
12
14
|
|
@@ -63,7 +65,7 @@ module Workato
|
|
63
65
|
oauth2_code: options[:oauth2_code],
|
64
66
|
redirect_url: options[:redirect_url],
|
65
67
|
refresh_token: options[:refresh_token],
|
66
|
-
recipe_id:
|
68
|
+
recipe_id: Workato::Connector::Sdk::Operation.recipe_id!
|
67
69
|
}
|
68
70
|
end
|
69
71
|
|
@@ -84,16 +86,21 @@ module Workato
|
|
84
86
|
)
|
85
87
|
@settings = settings_store.read
|
86
88
|
|
87
|
-
Workato::Connector::Sdk::Connection.
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
89
|
+
Workato::Connector::Sdk::Connection.multi_auth_selected_fallback = lambda do |options|
|
90
|
+
next @selected_auth_type if @selected_auth_type
|
91
|
+
|
92
|
+
with_user_interaction do
|
93
|
+
@selected_auth_type = multi_auth_selected_fallback(options)
|
94
|
+
end
|
95
|
+
end
|
92
96
|
|
93
|
-
|
94
|
-
|
97
|
+
Workato::Connector::Sdk::Connection.on_settings_update = lambda do |message, &refresher|
|
98
|
+
new_settings = refresher.call
|
99
|
+
break unless new_settings
|
95
100
|
|
101
|
+
with_user_interaction do
|
96
102
|
loop do
|
103
|
+
say(message)
|
97
104
|
answer = ask('Updated settings file with new connection attributes? (Yes or No)').to_s.downcase
|
98
105
|
break new_settings if %w[n no].include?(answer)
|
99
106
|
next unless %w[y yes].include?(answer)
|
@@ -101,8 +108,6 @@ module Workato
|
|
101
108
|
settings_store.update(new_settings)
|
102
109
|
break new_settings
|
103
110
|
end
|
104
|
-
ensure
|
105
|
-
$stdout.resume if verbose?
|
106
111
|
end
|
107
112
|
end
|
108
113
|
|
@@ -131,6 +136,11 @@ module Workato
|
|
131
136
|
|
132
137
|
def execute_path
|
133
138
|
connector.invoke(path, params)
|
139
|
+
rescue Workato::Connector::Sdk::InvalidMultiAuthDefinition => e
|
140
|
+
raise "#{e.message}. Please ensure:\n"\
|
141
|
+
"- 'selected' block is defined and returns value from 'options' list\n" \
|
142
|
+
"- settings file contains value expected by 'selected' block\n\n"\
|
143
|
+
'See more: https://docs.workato.com/developing-connectors/sdk/guides/authentication/multi_auth.html'
|
134
144
|
rescue Exception => e # rubocop:disable Lint/RescueException
|
135
145
|
raise DebugExceptionError, e if options[:debug]
|
136
146
|
|
@@ -181,6 +191,16 @@ module Workato
|
|
181
191
|
output
|
182
192
|
end
|
183
193
|
|
194
|
+
def with_user_interaction
|
195
|
+
$stdout.pause if verbose?
|
196
|
+
say('')
|
197
|
+
|
198
|
+
yield
|
199
|
+
ensure
|
200
|
+
say('')
|
201
|
+
$stdout.resume if verbose?
|
202
|
+
end
|
203
|
+
|
184
204
|
class ProgressLogger < SimpleDelegator
|
185
205
|
def initialize(progress)
|
186
206
|
super($stdout)
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Workato
|
4
|
+
module CLI
|
5
|
+
module MultiAuthSelectedFallback
|
6
|
+
private
|
7
|
+
|
8
|
+
def multi_auth_selected_fallback(options)
|
9
|
+
say('Please select current auth type for multi-auth connector:')
|
10
|
+
options = options.keys
|
11
|
+
options.each_with_index do |option, idx|
|
12
|
+
say "[#{idx + 1}] #{option}"
|
13
|
+
end
|
14
|
+
say '[q] <exit>'
|
15
|
+
say('')
|
16
|
+
|
17
|
+
multi_auth_selected_fallback = loop do
|
18
|
+
answer = ask('Your choice:').to_s.downcase
|
19
|
+
break if answer == 'q'
|
20
|
+
next unless /\d+/ =~ answer && options[answer.to_i - 1]
|
21
|
+
|
22
|
+
break options[answer.to_i - 1]
|
23
|
+
end
|
24
|
+
return unless multi_auth_selected_fallback
|
25
|
+
|
26
|
+
say('')
|
27
|
+
say('Put selected auth type in your settings file to avoid this message in future')
|
28
|
+
|
29
|
+
multi_auth_selected_fallback
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -3,11 +3,13 @@
|
|
3
3
|
|
4
4
|
require 'securerandom'
|
5
5
|
require 'workato/web/app'
|
6
|
+
require_relative './multi_auth_selected_fallback'
|
6
7
|
|
7
8
|
module Workato
|
8
9
|
module CLI
|
9
10
|
class OAuth2Command
|
10
11
|
include Thor::Shell
|
12
|
+
include MultiAuthSelectedFallback
|
11
13
|
|
12
14
|
AWAIT_CODE_TIMEOUT_INTERVAL = 180 # seconds
|
13
15
|
AWAIT_CODE_SLEEP_INTERVAL = 5 # seconds
|
@@ -24,6 +26,7 @@ module Workato
|
|
24
26
|
end
|
25
27
|
|
26
28
|
def call
|
29
|
+
ensure_oauth2_type
|
27
30
|
require_gems
|
28
31
|
start_webrick
|
29
32
|
|
@@ -94,16 +97,31 @@ module Workato
|
|
94
97
|
end
|
95
98
|
|
96
99
|
def stop_webrick
|
100
|
+
return unless @thread
|
101
|
+
|
97
102
|
Rack::Handler::WEBrick.shutdown
|
98
103
|
@thread.exit
|
99
104
|
end
|
100
105
|
|
106
|
+
def ensure_oauth2_type
|
107
|
+
unless connector.connection.authorization.oauth2?
|
108
|
+
raise 'Authorization type is not OAuth2. '\
|
109
|
+
'For multi-auth connector ensure correct auth type was used. '\
|
110
|
+
"Expected: 'oauth2', got: '#{connector.connection.authorization.type}''"
|
111
|
+
end
|
112
|
+
rescue Workato::Connector::Sdk::InvalidMultiAuthDefinition => e
|
113
|
+
raise "#{e.message}. Please ensure:\n"\
|
114
|
+
"- 'selected' block is defined and returns value from 'options' list\n" \
|
115
|
+
"- settings file contains value expected by 'selected' block\n\n"\
|
116
|
+
'See more: https://docs.workato.com/developing-connectors/sdk/guides/authentication/multi_auth.html'
|
117
|
+
end
|
118
|
+
|
101
119
|
def client
|
102
120
|
@client ||= OAuth2::Client.new(
|
103
|
-
connector.connection.authorization.client_id
|
104
|
-
connector.connection.authorization.client_secret
|
105
|
-
site: connector.connection.base_uri
|
106
|
-
token_url: connector.connection.authorization.token_url
|
121
|
+
connector.connection.authorization.client_id,
|
122
|
+
connector.connection.authorization.client_secret,
|
123
|
+
site: connector.connection.base_uri,
|
124
|
+
token_url: connector.connection.authorization.token_url,
|
107
125
|
redirect_uri: redirect_url
|
108
126
|
)
|
109
127
|
end
|
@@ -112,14 +130,14 @@ module Workato
|
|
112
130
|
return @authorize_url if defined?(@authorize_url)
|
113
131
|
|
114
132
|
@authorize_url =
|
115
|
-
if (authorization_url = connector.connection.authorization.authorization_url
|
133
|
+
if (authorization_url = connector.connection.authorization.authorization_url)
|
116
134
|
params = {
|
117
135
|
state: SecureRandom.hex(8),
|
118
|
-
client_id: connector.connection.authorization.client_id
|
136
|
+
client_id: connector.connection.authorization.client_id,
|
119
137
|
redirect_uri: redirect_url
|
120
|
-
}
|
138
|
+
}.with_indifferent_access
|
121
139
|
uri = URI(authorization_url)
|
122
|
-
uri.query = params.
|
140
|
+
uri.query = params.merge(Rack::Utils.parse_nested_query(uri.query || '')).to_param
|
123
141
|
uri.to_s
|
124
142
|
end
|
125
143
|
end
|
@@ -133,12 +151,25 @@ module Workato
|
|
133
151
|
end
|
134
152
|
|
135
153
|
def settings
|
136
|
-
@settings
|
154
|
+
return @settings if defined?(@settings)
|
155
|
+
|
156
|
+
@settings = settings_store.read
|
157
|
+
|
158
|
+
Workato::Connector::Sdk::Connection.multi_auth_selected_fallback = lambda do |options|
|
159
|
+
next @selected_auth_type if @selected_auth_type
|
160
|
+
|
161
|
+
with_user_interaction do
|
162
|
+
@selected_auth_type = multi_auth_selected_fallback(options)
|
163
|
+
end
|
164
|
+
end
|
165
|
+
|
166
|
+
@settings
|
137
167
|
end
|
138
168
|
|
139
169
|
def connector
|
140
170
|
@connector ||= Workato::Connector::Sdk::Connector.from_file(
|
141
|
-
options[:connector] || Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH
|
171
|
+
options[:connector] || Workato::Connector::Sdk::DEFAULT_CONNECTOR_PATH,
|
172
|
+
settings
|
142
173
|
)
|
143
174
|
end
|
144
175
|
|
@@ -156,8 +187,8 @@ module Workato
|
|
156
187
|
end
|
157
188
|
|
158
189
|
def acquire_token(code)
|
159
|
-
if connector.
|
160
|
-
tokens, _, extra_settings = connector.connection.authorization.acquire(
|
190
|
+
if connector.connection.authorization.source[:acquire]
|
191
|
+
tokens, _, extra_settings = connector.connection.authorization.acquire(nil, code, redirect_url)
|
161
192
|
tokens ||= {}
|
162
193
|
extra_settings ||= {}
|
163
194
|
extra_settings.merge(tokens)
|
@@ -178,6 +209,13 @@ module Workato
|
|
178
209
|
response = http.request(request)
|
179
210
|
response.body
|
180
211
|
end
|
212
|
+
|
213
|
+
def with_user_interaction
|
214
|
+
say('')
|
215
|
+
yield
|
216
|
+
ensure
|
217
|
+
say('')
|
218
|
+
end
|
181
219
|
end
|
182
220
|
end
|
183
221
|
end
|
@@ -3,9 +3,33 @@
|
|
3
3
|
|
4
4
|
require_relative './block_invocation_refinements'
|
5
5
|
|
6
|
+
using Workato::Extension::HashWithIndifferentAccess
|
7
|
+
|
6
8
|
module Workato
|
7
9
|
module Connector
|
8
10
|
module Sdk
|
11
|
+
module SorbetTypes
|
12
|
+
AcquireOutput = T.type_alias do
|
13
|
+
T.any(
|
14
|
+
# oauth2
|
15
|
+
[
|
16
|
+
HashWithIndifferentAccess, # tokens
|
17
|
+
T.untyped, # resource_owner_id
|
18
|
+
T.nilable(HashWithIndifferentAccess) # settings
|
19
|
+
],
|
20
|
+
[
|
21
|
+
HashWithIndifferentAccess, # tokens
|
22
|
+
T.untyped # resource_owner_id
|
23
|
+
],
|
24
|
+
[
|
25
|
+
HashWithIndifferentAccess # tokens
|
26
|
+
],
|
27
|
+
# custom_auth
|
28
|
+
HashWithIndifferentAccess
|
29
|
+
)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
9
33
|
class Connection
|
10
34
|
extend T::Sig
|
11
35
|
|
@@ -15,6 +39,7 @@ module Workato
|
|
15
39
|
attr_reader :source
|
16
40
|
|
17
41
|
cattr_accessor :on_settings_update
|
42
|
+
cattr_accessor :multi_auth_selected_fallback
|
18
43
|
|
19
44
|
sig do
|
20
45
|
params(
|
@@ -24,8 +49,8 @@ module Workato
|
|
24
49
|
).void
|
25
50
|
end
|
26
51
|
def initialize(connection: {}, methods: {}, settings: {})
|
27
|
-
@methods_source = T.let(methods
|
28
|
-
@source = T.let(connection
|
52
|
+
@methods_source = T.let(HashWithIndifferentAccess.wrap(methods), HashWithIndifferentAccess)
|
53
|
+
@source = T.let(HashWithIndifferentAccess.wrap(connection), HashWithIndifferentAccess)
|
29
54
|
@settings = T.let(settings, SorbetTypes::SettingsHash)
|
30
55
|
end
|
31
56
|
|
@@ -37,6 +62,7 @@ module Workato
|
|
37
62
|
sig { returns(HashWithIndifferentAccess) }
|
38
63
|
def settings
|
39
64
|
# we can't freeze or memoise because some developers modify it for storing something temporary in it.
|
65
|
+
# always return a new copy
|
40
66
|
@settings.with_indifferent_access
|
41
67
|
end
|
42
68
|
|
@@ -64,7 +90,10 @@ module Workato
|
|
64
90
|
|
65
91
|
sig { params(settings: T.nilable(SorbetTypes::SettingsHash)).returns(T.nilable(String)) }
|
66
92
|
def base_uri(settings = nil)
|
67
|
-
source[:base_uri]
|
93
|
+
return unless source[:base_uri]
|
94
|
+
|
95
|
+
merge_settings!(settings) if settings
|
96
|
+
Dsl::WithDsl.execute(self, self.settings, &source[:base_uri])
|
68
97
|
end
|
69
98
|
|
70
99
|
sig do
|
@@ -101,9 +130,6 @@ module Workato
|
|
101
130
|
class Authorization
|
102
131
|
extend T::Sig
|
103
132
|
|
104
|
-
sig { returns(HashWithIndifferentAccess) }
|
105
|
-
attr_reader :source
|
106
|
-
|
107
133
|
sig do
|
108
134
|
params(
|
109
135
|
connection: Connection,
|
@@ -123,6 +149,16 @@ module Workato
|
|
123
149
|
(source[:type].presence || 'none').to_s
|
124
150
|
end
|
125
151
|
|
152
|
+
sig { returns(T::Boolean) }
|
153
|
+
def oauth2?
|
154
|
+
!!(/oauth2/i =~ type)
|
155
|
+
end
|
156
|
+
|
157
|
+
sig { returns(T::Boolean) }
|
158
|
+
def multi?
|
159
|
+
@source[:type].to_s == 'multi'
|
160
|
+
end
|
161
|
+
|
126
162
|
sig { returns(T::Array[T.any(String, Symbol, Regexp, Integer)]) }
|
127
163
|
def refresh_on
|
128
164
|
Array.wrap(source[:refresh_on]).compact
|
@@ -135,10 +171,10 @@ module Workato
|
|
135
171
|
|
136
172
|
sig { params(settings: T.nilable(SorbetTypes::SettingsHash)).returns(T.nilable(String)) }
|
137
173
|
def client_id(settings = nil)
|
174
|
+
@connection.merge_settings!(settings) if settings
|
138
175
|
client_id = source[:client_id]
|
139
176
|
|
140
177
|
if client_id.is_a?(Proc)
|
141
|
-
@connection.merge_settings!(settings) if settings
|
142
178
|
Dsl::WithDsl.execute(@connection, @connection.settings, &client_id)
|
143
179
|
else
|
144
180
|
client_id
|
@@ -147,10 +183,10 @@ module Workato
|
|
147
183
|
|
148
184
|
sig { params(settings: T.nilable(SorbetTypes::SettingsHash)).returns(T.nilable(String)) }
|
149
185
|
def client_secret(settings = nil)
|
186
|
+
@connection.merge_settings!(settings) if settings
|
150
187
|
client_secret_source = source[:client_secret]
|
151
188
|
|
152
189
|
if client_secret_source.is_a?(Proc)
|
153
|
-
@connection.merge_settings!(settings) if settings
|
154
190
|
Dsl::WithDsl.execute(@connection, @connection.settings, &client_secret_source)
|
155
191
|
else
|
156
192
|
client_secret_source
|
@@ -159,12 +195,18 @@ module Workato
|
|
159
195
|
|
160
196
|
sig { params(settings: T.nilable(SorbetTypes::SettingsHash)).returns(T.nilable(String)) }
|
161
197
|
def authorization_url(settings = nil)
|
162
|
-
|
198
|
+
@connection.merge_settings!(settings) if settings
|
199
|
+
return unless source[:authorization_url]
|
200
|
+
|
201
|
+
Dsl::WithDsl.execute(@connection, @connection.settings, &source[:authorization_url])
|
163
202
|
end
|
164
203
|
|
165
204
|
sig { params(settings: T.nilable(SorbetTypes::SettingsHash)).returns(T.nilable(String)) }
|
166
205
|
def token_url(settings = nil)
|
167
|
-
|
206
|
+
@connection.merge_settings!(settings) if settings
|
207
|
+
return unless source[:token_url]
|
208
|
+
|
209
|
+
Dsl::WithDsl.execute(@connection, @connection.settings, &source[:token_url])
|
168
210
|
end
|
169
211
|
|
170
212
|
sig do
|
@@ -172,9 +214,10 @@ module Workato
|
|
172
214
|
settings: T.nilable(SorbetTypes::SettingsHash),
|
173
215
|
oauth2_code: T.nilable(String),
|
174
216
|
redirect_url: T.nilable(String)
|
175
|
-
).returns(
|
217
|
+
).returns(T.nilable(SorbetTypes::AcquireOutput))
|
176
218
|
end
|
177
219
|
def acquire(settings = nil, oauth2_code = nil, redirect_url = nil)
|
220
|
+
@connection.merge_settings!(settings) if settings
|
178
221
|
acquire_proc = source[:acquire]
|
179
222
|
raise InvalidDefinitionError, "Expect 'acquire' block" unless acquire_proc
|
180
223
|
|
@@ -202,7 +245,7 @@ module Workato
|
|
202
245
|
).returns(T::Boolean)
|
203
246
|
end
|
204
247
|
def refresh?(http_code, http_body, exception)
|
205
|
-
return false unless
|
248
|
+
return false unless oauth2? || source[:acquire].present?
|
206
249
|
|
207
250
|
refresh_on = self.refresh_on
|
208
251
|
refresh_on.blank? || refresh_on.any? do |pattern|
|
@@ -214,10 +257,10 @@ module Workato
|
|
214
257
|
|
215
258
|
sig { params(settings: HashWithIndifferentAccess).returns(T.nilable(HashWithIndifferentAccess)) }
|
216
259
|
def refresh!(settings)
|
217
|
-
if
|
260
|
+
if oauth2?
|
218
261
|
refresh_oauth2_token(settings)
|
219
262
|
elsif source[:acquire].present?
|
220
|
-
acquire(settings)
|
263
|
+
T.cast(acquire(settings), T.nilable(HashWithIndifferentAccess))
|
221
264
|
end
|
222
265
|
end
|
223
266
|
|
@@ -230,6 +273,7 @@ module Workato
|
|
230
273
|
)
|
231
274
|
end
|
232
275
|
def refresh(settings = nil, refresh_token = nil)
|
276
|
+
@connection.merge_settings!(settings) if settings
|
233
277
|
refresh_proc = source[:refresh]
|
234
278
|
raise InvalidDefinitionError, "Expect 'refresh' block" unless refresh_proc
|
235
279
|
|
@@ -244,6 +288,27 @@ module Workato
|
|
244
288
|
end
|
245
289
|
end
|
246
290
|
|
291
|
+
sig { returns(HashWithIndifferentAccess) }
|
292
|
+
def source
|
293
|
+
return @source unless multi?
|
294
|
+
|
295
|
+
unless @source[:selected]
|
296
|
+
raise InvalidMultiAuthDefinition, "Multi-auth connection must define 'selected' block"
|
297
|
+
end
|
298
|
+
|
299
|
+
if @source[:options].blank?
|
300
|
+
raise InvalidMultiAuthDefinition, "Multi-auth connection must define 'options' list"
|
301
|
+
end
|
302
|
+
|
303
|
+
selected_auth_key = @source[:selected].call(@connection.settings)
|
304
|
+
selected_auth_key ||= @connection.multi_auth_selected_fallback&.call(@source[:options])
|
305
|
+
selected_auth_value = @source.dig(:options, selected_auth_key)
|
306
|
+
|
307
|
+
raise UnresolvedMultiAuthOptionError, selected_auth_key unless selected_auth_value
|
308
|
+
|
309
|
+
selected_auth_value
|
310
|
+
end
|
311
|
+
|
247
312
|
private
|
248
313
|
|
249
314
|
sig { returns(HashWithIndifferentAccess) }
|
@@ -266,7 +331,10 @@ module Workato
|
|
266
331
|
sig { params(settings: HashWithIndifferentAccess).returns(HashWithIndifferentAccess) }
|
267
332
|
def refresh_oauth2_token_using_refresh(settings)
|
268
333
|
new_tokens, new_settings = refresh(settings, settings[:refresh_token])
|
269
|
-
new_tokens.
|
334
|
+
new_tokens = HashWithIndifferentAccess.wrap(new_tokens)
|
335
|
+
return new_tokens unless new_settings
|
336
|
+
|
337
|
+
new_tokens.merge(new_settings)
|
270
338
|
end
|
271
339
|
|
272
340
|
sig { params(settings: HashWithIndifferentAccess).returns(HashWithIndifferentAccess) }
|
@@ -1,6 +1,8 @@
|
|
1
1
|
# typed: strict
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
|
+
using Workato::Extension::HashWithIndifferentAccess
|
5
|
+
|
4
6
|
module Workato
|
5
7
|
module Connector
|
6
8
|
module Sdk
|
@@ -21,10 +23,10 @@ module Workato
|
|
21
23
|
|
22
24
|
sig { params(definition: SorbetTypes::SourceHash, settings: SorbetTypes::SettingsHash).void }
|
23
25
|
def initialize(definition, settings = {})
|
24
|
-
@source = T.let(definition
|
25
|
-
@settings = T.let(settings
|
26
|
-
@connection_source = T.let(@source[:connection]
|
27
|
-
@methods_source = T.let(@source[:methods]
|
26
|
+
@source = T.let(HashWithIndifferentAccess.wrap(definition), HashWithIndifferentAccess)
|
27
|
+
@settings = T.let(HashWithIndifferentAccess.wrap(settings), HashWithIndifferentAccess)
|
28
|
+
@connection_source = T.let(HashWithIndifferentAccess.wrap(@source[:connection]), HashWithIndifferentAccess)
|
29
|
+
@methods_source = T.let(HashWithIndifferentAccess.wrap(@source[:methods]), HashWithIndifferentAccess)
|
28
30
|
end
|
29
31
|
|
30
32
|
sig { params(path: String, params: T::Hash[Symbol, T.untyped]).returns(T.untyped) }
|
@@ -2,6 +2,9 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'aws-sigv4'
|
5
|
+
require 'workato/utilities/xml'
|
6
|
+
|
7
|
+
using Workato::Extension::HashWithIndifferentAccess
|
5
8
|
|
6
9
|
module Workato
|
7
10
|
module Connector
|
@@ -55,7 +58,7 @@ module Workato
|
|
55
58
|
method: method,
|
56
59
|
path: path,
|
57
60
|
params: params,
|
58
|
-
headers: (headers
|
61
|
+
headers: HashWithIndifferentAccess.wrap(headers),
|
59
62
|
payload: payload
|
60
63
|
)
|
61
64
|
|
@@ -134,7 +137,7 @@ module Workato
|
|
134
137
|
headers: headers,
|
135
138
|
method: :get
|
136
139
|
)
|
137
|
-
response = Workato::
|
140
|
+
response = Workato::Utilities::Xml.parse_xml_to_hash(response.body)
|
138
141
|
|
139
142
|
temp_credentials = response.dig('AssumeRoleResponse', 0, 'AssumeRoleResult', 0, 'Credentials', 0)
|
140
143
|
{
|
@@ -0,0 +1,125 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'csv'
|
5
|
+
|
6
|
+
module Workato
|
7
|
+
module Connector
|
8
|
+
module Sdk
|
9
|
+
CsvError = Class.new(Sdk::RuntimeError)
|
10
|
+
|
11
|
+
CsvFormatError = Class.new(CsvError)
|
12
|
+
|
13
|
+
class CsvFileTooBigError < CsvError
|
14
|
+
extend T::Sig
|
15
|
+
|
16
|
+
sig { returns(Integer) }
|
17
|
+
attr_reader :size
|
18
|
+
|
19
|
+
sig { returns(Integer) }
|
20
|
+
attr_reader :max
|
21
|
+
|
22
|
+
sig { params(size: Integer, max: Integer).void }
|
23
|
+
def initialize(size, max)
|
24
|
+
super("CSV file is too big. Max allowed: #{max.to_s(:human_size)}, got: #{size.to_s(:human_size)}")
|
25
|
+
@size = T.let(size, Integer)
|
26
|
+
@max = T.let(max, Integer)
|
27
|
+
end
|
28
|
+
end
|
29
|
+
|
30
|
+
class CsvFileTooManyLinesError < CsvError
|
31
|
+
extend T::Sig
|
32
|
+
|
33
|
+
sig { returns(Integer) }
|
34
|
+
attr_reader :max
|
35
|
+
|
36
|
+
sig { params(max: Integer).void }
|
37
|
+
def initialize(max)
|
38
|
+
super("CSV file has too many lines. Max allowed: #{max}")
|
39
|
+
@max = T.let(max, Integer)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
module Dsl
|
44
|
+
module Csv
|
45
|
+
extend T::Sig
|
46
|
+
|
47
|
+
MAX_FILE_SIZE_FOR_PARSE = T.let(30.megabytes, Integer)
|
48
|
+
private_constant :MAX_FILE_SIZE_FOR_PARSE
|
49
|
+
|
50
|
+
MAX_LINES_FOR_PARSE = 65_000
|
51
|
+
private_constant :MAX_LINES_FOR_PARSE
|
52
|
+
|
53
|
+
class << self
|
54
|
+
extend T::Sig
|
55
|
+
|
56
|
+
sig do
|
57
|
+
params(
|
58
|
+
str: String,
|
59
|
+
headers: T.any(T::Boolean, T::Array[String], String),
|
60
|
+
col_sep: T.nilable(String),
|
61
|
+
row_sep: T.nilable(String),
|
62
|
+
quote_char: T.nilable(String),
|
63
|
+
skip_blanks: T.nilable(T::Boolean),
|
64
|
+
skip_first_line: T::Boolean
|
65
|
+
).returns(
|
66
|
+
T::Array[T::Hash[String, T.untyped]]
|
67
|
+
)
|
68
|
+
end
|
69
|
+
def parse(str, headers:, col_sep: nil, row_sep: nil, quote_char: nil, skip_blanks: nil,
|
70
|
+
skip_first_line: false)
|
71
|
+
if str.bytesize > MAX_FILE_SIZE_FOR_PARSE
|
72
|
+
raise CsvFileTooBigError.new(str.bytesize, MAX_FILE_SIZE_FOR_PARSE)
|
73
|
+
end
|
74
|
+
|
75
|
+
index = 0
|
76
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
77
|
+
skip_blanks: skip_blanks }.compact
|
78
|
+
Enumerator.new do |consumer|
|
79
|
+
CSV.parse(str, options) do |row|
|
80
|
+
if index.zero? && skip_first_line
|
81
|
+
index += 1
|
82
|
+
next
|
83
|
+
end
|
84
|
+
if index == MAX_LINES_FOR_PARSE
|
85
|
+
raise CsvFileTooManyLinesError, MAX_LINES_FOR_PARSE
|
86
|
+
end
|
87
|
+
|
88
|
+
index += 1
|
89
|
+
consumer.yield(T.cast(row, CSV::Row).to_hash)
|
90
|
+
end
|
91
|
+
end.to_a
|
92
|
+
rescue CSV::MalformedCSVError => e
|
93
|
+
raise CsvFormatError, e
|
94
|
+
rescue ArgumentError => e
|
95
|
+
raise Sdk::RuntimeError, e.message
|
96
|
+
end
|
97
|
+
|
98
|
+
sig do
|
99
|
+
params(
|
100
|
+
str: T.nilable(String),
|
101
|
+
headers: T.nilable(T::Array[String]),
|
102
|
+
col_sep: T.nilable(String),
|
103
|
+
row_sep: T.nilable(String),
|
104
|
+
quote_char: T.nilable(String),
|
105
|
+
force_quotes: T.nilable(T::Boolean),
|
106
|
+
blk: T.proc.params(csv: CSV).void
|
107
|
+
).returns(
|
108
|
+
String
|
109
|
+
)
|
110
|
+
end
|
111
|
+
def generate(str = nil, headers: nil, col_sep: nil, row_sep: nil, quote_char: nil, force_quotes: nil, &blk)
|
112
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
113
|
+
force_quotes: force_quotes }.compact
|
114
|
+
options[:write_headers] = options[:headers].present?
|
115
|
+
|
116
|
+
::CSV.generate(str || String.new, options, &blk)
|
117
|
+
rescue ArgumentError => e
|
118
|
+
raise Sdk::RuntimeError, e.message
|
119
|
+
end
|
120
|
+
end
|
121
|
+
end
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|