workato-connector-sdk 1.2.0 → 1.3.1
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/.yardopts +8 -0
- data/README.md +2 -6
- data/VERSION +1 -0
- data/lib/workato/cli/edit_command.rb +3 -1
- data/lib/workato/cli/exec_command.rb +76 -10
- data/lib/workato/cli/generate_command.rb +3 -2
- data/lib/workato/cli/main.rb +18 -10
- data/lib/workato/cli/oauth2_command.rb +4 -4
- data/lib/workato/cli/push_command.rb +23 -7
- data/lib/workato/cli/schema_command.rb +20 -6
- data/lib/workato/connector/sdk/account_properties.rb +3 -3
- data/lib/workato/connector/sdk/action.rb +20 -70
- data/lib/workato/connector/sdk/block_invocation_refinements.rb +4 -11
- data/lib/workato/connector/sdk/connection.rb +44 -21
- data/lib/workato/connector/sdk/connector.rb +73 -76
- data/lib/workato/connector/sdk/core.rb +62 -0
- data/lib/workato/connector/sdk/dsl/aws.rb +13 -3
- data/lib/workato/connector/sdk/dsl/call.rb +1 -1
- data/lib/workato/connector/sdk/dsl/csv_package.rb +133 -0
- data/lib/workato/connector/sdk/dsl/error.rb +2 -0
- data/lib/workato/connector/sdk/dsl/execution_context.rb +3 -0
- data/lib/workato/connector/sdk/dsl/http.rb +7 -2
- data/lib/workato/connector/sdk/dsl/reinvoke_after.rb +84 -0
- data/lib/workato/connector/sdk/dsl/stream_package.rb +59 -0
- data/lib/workato/connector/sdk/dsl/time.rb +0 -14
- data/lib/workato/connector/sdk/dsl/workato_package.rb +152 -0
- data/lib/workato/connector/sdk/dsl.rb +65 -10
- data/lib/workato/connector/sdk/errors.rb +28 -11
- data/lib/workato/connector/sdk/object_definitions.rb +59 -18
- data/lib/workato/connector/sdk/operation.rb +10 -3
- data/lib/workato/connector/sdk/request.rb +67 -26
- data/lib/workato/connector/sdk/schema/field/convertors.rb +2 -2
- data/lib/workato/connector/sdk/schema.rb +10 -7
- data/lib/workato/connector/sdk/settings.rb +13 -2
- data/lib/workato/connector/sdk/stream.rb +262 -0
- data/lib/workato/connector/sdk/streams.rb +72 -0
- data/lib/workato/connector/sdk/summarize.rb +4 -2
- data/lib/workato/connector/sdk/trigger.rb +14 -7
- data/lib/workato/connector/sdk/version.rb +1 -1
- data/lib/workato/connector/sdk.rb +20 -46
- data/lib/workato/extension/array.rb +2 -0
- data/lib/workato/extension/case_sensitive_headers.rb +0 -1
- data/lib/workato/extension/content_encoding_decoder.rb +2 -0
- data/lib/workato/extension/currency/countries.rb +79 -0
- data/lib/workato/extension/currency/countries.yml +18433 -0
- data/lib/workato/extension/currency/currencies.rb +55 -0
- data/lib/workato/extension/currency/currencies.yml +479 -0
- data/lib/workato/extension/currency.rb +73 -5
- data/lib/workato/extension/enumerable.rb +2 -2
- data/lib/workato/extension/metadata_fix_wrap_kw_args.rb +11 -0
- data/lib/workato/extension/string.rb +23 -111
- data/lib/workato/testing/vcr_encrypted_cassette_serializer.rb +2 -0
- data/lib/workato/testing/vcr_multipart_body_matcher.rb +1 -0
- data/lib/workato/types/binary.rb +99 -0
- data/lib/workato/types/unicode_string.rb +62 -0
- metadata +34 -62
- data/lib/workato/connector/sdk/dsl/csv.rb +0 -125
- data/lib/workato/connector/sdk/dsl/workato_code_lib.rb +0 -167
- data/lib/workato/connector/sdk/schema/type/unicode_string.rb +0 -23
@@ -0,0 +1,133 @@
|
|
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
|
+
class CsvPackage
|
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
|
+
sig do
|
54
|
+
params(
|
55
|
+
str: String,
|
56
|
+
headers: T.any(T::Boolean, T::Array[String], String),
|
57
|
+
col_sep: T.nilable(String),
|
58
|
+
row_sep: T.nilable(String),
|
59
|
+
quote_char: T.nilable(String),
|
60
|
+
skip_blanks: T.nilable(T::Boolean),
|
61
|
+
skip_first_line: T::Boolean
|
62
|
+
).returns(
|
63
|
+
T::Array[T::Hash[String, T.untyped]]
|
64
|
+
)
|
65
|
+
end
|
66
|
+
def parse(str, headers:, col_sep: nil, row_sep: nil, quote_char: nil, skip_blanks: nil,
|
67
|
+
skip_first_line: false)
|
68
|
+
if str.bytesize > MAX_FILE_SIZE_FOR_PARSE
|
69
|
+
raise CsvFileTooBigError.new(str.bytesize, MAX_FILE_SIZE_FOR_PARSE)
|
70
|
+
end
|
71
|
+
|
72
|
+
index = 0
|
73
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
74
|
+
skip_blanks: skip_blanks }.compact
|
75
|
+
Enumerator.new do |consumer|
|
76
|
+
CSV.parse(str, **options) do |row|
|
77
|
+
if index.zero? && skip_first_line
|
78
|
+
index += 1
|
79
|
+
next
|
80
|
+
end
|
81
|
+
if index == MAX_LINES_FOR_PARSE
|
82
|
+
raise CsvFileTooManyLinesError, MAX_LINES_FOR_PARSE
|
83
|
+
end
|
84
|
+
|
85
|
+
index += 1
|
86
|
+
consumer.yield(T.cast(row, CSV::Row).to_hash)
|
87
|
+
end
|
88
|
+
end.to_a
|
89
|
+
rescue CSV::MalformedCSVError => e
|
90
|
+
raise CsvFormatError, e
|
91
|
+
rescue ArgumentError => e
|
92
|
+
raise Sdk::RuntimeError, e.message
|
93
|
+
end
|
94
|
+
|
95
|
+
sig do
|
96
|
+
params(
|
97
|
+
str: T.nilable(String),
|
98
|
+
headers: T.nilable(T::Array[String]),
|
99
|
+
col_sep: T.nilable(String),
|
100
|
+
row_sep: T.nilable(String),
|
101
|
+
quote_char: T.nilable(String),
|
102
|
+
force_quotes: T.nilable(T::Boolean),
|
103
|
+
blk: T.proc.params(csv: CSV).void
|
104
|
+
).returns(
|
105
|
+
String
|
106
|
+
)
|
107
|
+
end
|
108
|
+
def generate(str = nil, headers: nil, col_sep: nil, row_sep: nil, quote_char: nil, force_quotes: nil, &blk)
|
109
|
+
options = { col_sep: col_sep, row_sep: row_sep, quote_char: quote_char, headers: headers,
|
110
|
+
force_quotes: force_quotes }.compact
|
111
|
+
options[:write_headers] = options[:headers].present?
|
112
|
+
|
113
|
+
::CSV.generate(str || String.new, **options, &blk)
|
114
|
+
rescue ArgumentError => e
|
115
|
+
raise Sdk::RuntimeError, e.message
|
116
|
+
end
|
117
|
+
|
118
|
+
private
|
119
|
+
|
120
|
+
T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
|
121
|
+
def method_missing(symbol, *_args)
|
122
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.csv')
|
123
|
+
end
|
124
|
+
|
125
|
+
T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
|
126
|
+
def respond_to_missing?(*_args)
|
127
|
+
false
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
end
|
@@ -2,6 +2,7 @@
|
|
2
2
|
# frozen_string_literal: true
|
3
3
|
|
4
4
|
require 'securerandom'
|
5
|
+
require 'active_support/core_ext/class/attribute'
|
5
6
|
|
6
7
|
module Workato
|
7
8
|
module Connector
|
@@ -37,6 +38,8 @@ module Workato
|
|
37
38
|
T.unsafe(self).recipe_id.reverse
|
38
39
|
end
|
39
40
|
end
|
41
|
+
|
42
|
+
private_constant :ClassMethods
|
40
43
|
end
|
41
44
|
end
|
42
45
|
end
|
@@ -8,8 +8,13 @@ module Workato
|
|
8
8
|
# https://docs.workato.com/developing-connectors/sdk/sdk-reference/http.html#http-methods
|
9
9
|
module HTTP
|
10
10
|
PARALLEL_SUCCESS_INDEX = 0
|
11
|
+
private_constant :PARALLEL_SUCCESS_INDEX
|
12
|
+
|
11
13
|
PARALLEL_RESULTS_INDEX = 1
|
14
|
+
private_constant :PARALLEL_RESULTS_INDEX
|
15
|
+
|
12
16
|
PARALLEL_ERRORS_INDEX = 2
|
17
|
+
private_constant :PARALLEL_ERRORS_INDEX
|
13
18
|
|
14
19
|
def get(url, params = {})
|
15
20
|
http_request(url, method: 'GET').params(params).response_format_json
|
@@ -52,8 +57,8 @@ module Workato
|
|
52
57
|
response = nil
|
53
58
|
exception = nil
|
54
59
|
begin
|
55
|
-
response = request.
|
56
|
-
rescue
|
60
|
+
response = request.response!
|
61
|
+
rescue StandardError => e
|
57
62
|
exception = e.to_s
|
58
63
|
end
|
59
64
|
result[PARALLEL_SUCCESS_INDEX] &&= exception.nil?
|
@@ -0,0 +1,84 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Workato
|
5
|
+
module Connector
|
6
|
+
module Sdk
|
7
|
+
module Dsl
|
8
|
+
module ReinvokeAfter
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig do
|
12
|
+
params(
|
13
|
+
continue: T::Hash[T.untyped, T.untyped],
|
14
|
+
temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
|
15
|
+
).void
|
16
|
+
end
|
17
|
+
def checkpoint!(continue:, temp_output: nil)
|
18
|
+
# no-op
|
19
|
+
end
|
20
|
+
|
21
|
+
sig do
|
22
|
+
params(
|
23
|
+
seconds: T.any(Integer, Float),
|
24
|
+
continue: T::Hash[T.untyped, T.untyped],
|
25
|
+
temp_output: T.nilable(T::Hash[T.untyped, T.untyped])
|
26
|
+
).void
|
27
|
+
end
|
28
|
+
def reinvoke_after(seconds:, continue:, temp_output: nil) # rubocop:disable Lint/UnusedMethodArgument
|
29
|
+
Kernel.throw REINVOKE_AFTER_SIGNAL, ReinvokeParams.new(
|
30
|
+
seconds: seconds,
|
31
|
+
continue: continue
|
32
|
+
)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
MAX_REINVOKES = 5
|
38
|
+
private_constant :MAX_REINVOKES
|
39
|
+
|
40
|
+
REINVOKE_AFTER_SIGNAL = :reinvoke_after
|
41
|
+
private_constant :REINVOKE_AFTER_SIGNAL
|
42
|
+
|
43
|
+
class ReinvokeParams < T::Struct
|
44
|
+
prop :seconds, T.any(Float, Integer)
|
45
|
+
prop :continue, T::Hash[T.untyped, T.untyped]
|
46
|
+
end
|
47
|
+
private_constant :ReinvokeParams
|
48
|
+
|
49
|
+
sig { params(continue: T::Hash[T.any(Symbol, String), T.untyped], _blk: Proc).returns(T.untyped) }
|
50
|
+
def loop_reinvoke_after(continue, &_blk)
|
51
|
+
reinvokes_remaining = T.let(reinvoke_limit, Integer)
|
52
|
+
|
53
|
+
Kernel.loop do
|
54
|
+
reinvoke_after = Kernel.catch(REINVOKE_AFTER_SIGNAL) do
|
55
|
+
return yield(continue)
|
56
|
+
end
|
57
|
+
|
58
|
+
if reinvokes_remaining.zero?
|
59
|
+
Kernel.raise "Max number of reinvokes on SDK Gem reached. Current limit is #{reinvoke_limit}"
|
60
|
+
end
|
61
|
+
|
62
|
+
reinvokes_remaining -= 1
|
63
|
+
|
64
|
+
reinvoke_after = T.cast(reinvoke_after, ReinvokeParams)
|
65
|
+
reinvoke_sleep(reinvoke_after.seconds)
|
66
|
+
continue = reinvoke_after.continue
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
sig { params(seconds: T.any(Float, Integer)).void }
|
71
|
+
def reinvoke_sleep(seconds)
|
72
|
+
Kernel.sleep((ENV['WAIT_REINVOKE_AFTER'].presence || seconds).to_f)
|
73
|
+
end
|
74
|
+
|
75
|
+
sig { returns(Integer) }
|
76
|
+
def reinvoke_limit
|
77
|
+
@reinvoke_limit = T.let(@reinvoke_limit, T.nilable(Integer))
|
78
|
+
@reinvoke_limit ||= (ENV['MAX_REINVOKES'].presence || MAX_REINVOKES).to_i
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,59 @@
|
|
1
|
+
# typed: strict
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
module Workato
|
5
|
+
module Connector
|
6
|
+
module Sdk
|
7
|
+
module Dsl
|
8
|
+
class StreamPackage
|
9
|
+
extend T::Sig
|
10
|
+
|
11
|
+
sig { params(streams: Streams, connection: Connection).void }
|
12
|
+
def initialize(streams:, connection:)
|
13
|
+
@streams = streams
|
14
|
+
@connection = connection
|
15
|
+
end
|
16
|
+
|
17
|
+
sig do
|
18
|
+
params(
|
19
|
+
stream: T.any(Stream::Proxy, String, T::Hash[T.untyped, T.untyped]),
|
20
|
+
from: T.nilable(Integer),
|
21
|
+
frame_size: T.nilable(Integer),
|
22
|
+
blk: SorbetTypes::StreamInProc
|
23
|
+
).returns(T.untyped)
|
24
|
+
end
|
25
|
+
def in(stream, from: nil, frame_size: nil, &blk)
|
26
|
+
if stream.is_a?(Hash) && stream[:__stream__] && stream[:chunks].nil?
|
27
|
+
stream = out(stream[:name], stream[:input] || {})
|
28
|
+
end
|
29
|
+
|
30
|
+
Stream.each_chunk(stream: stream, from: from, frame_size: frame_size, &blk)
|
31
|
+
end
|
32
|
+
|
33
|
+
sig { params(stream_name: String, input: SorbetTypes::StreamInputHash).returns(Stream::Proxy) }
|
34
|
+
def out(stream_name, input = {})
|
35
|
+
Stream::Proxy.new(input: input, name: stream_name, stream: streams[stream_name])
|
36
|
+
end
|
37
|
+
|
38
|
+
private
|
39
|
+
|
40
|
+
T::Sig::WithoutRuntime.sig { params(symbol: T.any(String, Symbol), _args: T.untyped).void }
|
41
|
+
def method_missing(symbol, *_args)
|
42
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato.stream')
|
43
|
+
end
|
44
|
+
|
45
|
+
T::Sig::WithoutRuntime.sig { params(_args: T.untyped).returns(T::Boolean) }
|
46
|
+
def respond_to_missing?(*_args)
|
47
|
+
false
|
48
|
+
end
|
49
|
+
|
50
|
+
sig { returns(Connection) }
|
51
|
+
attr_reader :connection
|
52
|
+
|
53
|
+
sig { returns(Streams) }
|
54
|
+
attr_reader :streams
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
@@ -18,17 +18,3 @@ module Workato
|
|
18
18
|
end
|
19
19
|
end
|
20
20
|
end
|
21
|
-
|
22
|
-
begin
|
23
|
-
if ENV['TZ'].present? && ENV['TZ'] != 'UTC'
|
24
|
-
warn "WARNING: TZ environment variable is set to '#{ENV['TZ']}'. Set TZ=UTC for consistency with Workato platform'"
|
25
|
-
else
|
26
|
-
ENV['TZ'] = 'UTC'
|
27
|
-
end
|
28
|
-
::Time.zone = Workato::Connector::Sdk::DEFAULT_TIME_ZONE
|
29
|
-
rescue TZInfo::DataSourceNotFound
|
30
|
-
puts ''
|
31
|
-
puts "tzinfo-data is not present. Please install gem 'tzinfo-data' by 'gem install tzinfo-data'"
|
32
|
-
puts ''
|
33
|
-
exit!
|
34
|
-
end
|
@@ -0,0 +1,152 @@
|
|
1
|
+
# typed: true
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'jwt'
|
5
|
+
require_relative './csv_package'
|
6
|
+
require_relative './stream_package'
|
7
|
+
|
8
|
+
using Workato::Extension::HashWithIndifferentAccess
|
9
|
+
|
10
|
+
module Workato
|
11
|
+
module Connector
|
12
|
+
module Sdk
|
13
|
+
module Dsl
|
14
|
+
class WorkatoPackage
|
15
|
+
JWT_ALGORITHMS = %w[RS256 RS384 RS512].freeze
|
16
|
+
private_constant :JWT_ALGORITHMS
|
17
|
+
|
18
|
+
JWT_RSA_KEY_MIN_LENGTH = 2048
|
19
|
+
private_constant :JWT_RSA_KEY_MIN_LENGTH
|
20
|
+
|
21
|
+
VERIFY_RCA_ALGORITHMS = %w[SHA SHA1 SHA224 SHA256 SHA384 SHA512].freeze
|
22
|
+
private_constant :VERIFY_RCA_ALGORITHMS
|
23
|
+
|
24
|
+
RANDOM_SIZE = 32
|
25
|
+
private_constant :RANDOM_SIZE
|
26
|
+
|
27
|
+
ALLOWED_KEY_SIZES = [128, 192, 256].freeze
|
28
|
+
private_constant :ALLOWED_KEY_SIZES
|
29
|
+
|
30
|
+
def initialize(streams:, connection:)
|
31
|
+
@streams = streams
|
32
|
+
@connection = connection
|
33
|
+
end
|
34
|
+
|
35
|
+
def jwt_encode_rs256(payload, key, header_fields = {})
|
36
|
+
jwt_encode(payload, key, 'RS256', header_fields)
|
37
|
+
end
|
38
|
+
|
39
|
+
def jwt_encode(payload, key, algorithm, header_fields = {})
|
40
|
+
algorithm = algorithm.to_s.upcase
|
41
|
+
unless JWT_ALGORITHMS.include?(algorithm)
|
42
|
+
raise "Unsupported signing method. Supports only #{JWT_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
|
43
|
+
end
|
44
|
+
|
45
|
+
rsa_private = OpenSSL::PKey::RSA.new(key)
|
46
|
+
if rsa_private.n.num_bits < JWT_RSA_KEY_MIN_LENGTH
|
47
|
+
raise "A RSA key of size #{JWT_RSA_KEY_MIN_LENGTH} bits or larger MUST be used with JWT."
|
48
|
+
end
|
49
|
+
|
50
|
+
header_fields = HashWithIndifferentAccess.wrap(header_fields).except(:typ, :alg)
|
51
|
+
::JWT.encode(payload, rsa_private, algorithm, header_fields)
|
52
|
+
end
|
53
|
+
|
54
|
+
def verify_rsa(payload, certificate, signature, algorithm = 'SHA256')
|
55
|
+
algorithm = algorithm.to_s.upcase
|
56
|
+
unless VERIFY_RCA_ALGORITHMS.include?(algorithm)
|
57
|
+
raise "Unsupported signing method. Supports only #{VERIFY_RCA_ALGORITHMS.join(', ')}. Got: '#{algorithm}'"
|
58
|
+
end
|
59
|
+
|
60
|
+
cert = OpenSSL::X509::Certificate.new(certificate)
|
61
|
+
digest = OpenSSL::Digest.new(algorithm)
|
62
|
+
cert.public_key.verify(digest, signature, payload)
|
63
|
+
rescue OpenSSL::PKey::PKeyError
|
64
|
+
raise 'An error occurred during signature verification. Check arguments'
|
65
|
+
rescue OpenSSL::X509::CertificateError
|
66
|
+
raise 'Invalid certificate format'
|
67
|
+
end
|
68
|
+
|
69
|
+
def parse_yaml(yaml)
|
70
|
+
::Psych.safe_load(yaml)
|
71
|
+
rescue ::Psych::DisallowedClass => e
|
72
|
+
raise e.message
|
73
|
+
end
|
74
|
+
|
75
|
+
def render_yaml(obj)
|
76
|
+
::Psych.dump(obj)
|
77
|
+
end
|
78
|
+
|
79
|
+
def parse_json(source)
|
80
|
+
JSON.parse(source)
|
81
|
+
rescue JSON::ParserError => e
|
82
|
+
raise JSONResponseFormatError, e
|
83
|
+
end
|
84
|
+
|
85
|
+
def uuid
|
86
|
+
SecureRandom.uuid
|
87
|
+
end
|
88
|
+
|
89
|
+
def random_bytes(len)
|
90
|
+
unless (len.is_a? ::Integer) && (len <= RANDOM_SIZE)
|
91
|
+
raise "The requested length or random bytes sequence should be <= #{RANDOM_SIZE}"
|
92
|
+
end
|
93
|
+
|
94
|
+
Types::Binary.new(::OpenSSL::Random.random_bytes(len))
|
95
|
+
end
|
96
|
+
|
97
|
+
def aes_cbc_encrypt(string, key, init_vector = nil)
|
98
|
+
key_size = key.bytesize * 8
|
99
|
+
unless ALLOWED_KEY_SIZES.include?(key_size)
|
100
|
+
raise 'Incorrect key size for AES'
|
101
|
+
end
|
102
|
+
|
103
|
+
cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
|
104
|
+
cipher.encrypt
|
105
|
+
cipher.key = key
|
106
|
+
cipher.iv = init_vector if init_vector.present?
|
107
|
+
Types::Binary.new(cipher.update(string) + cipher.final)
|
108
|
+
end
|
109
|
+
|
110
|
+
def aes_cbc_decrypt(string, key, init_vector = nil)
|
111
|
+
key_size = key.bytesize * 8
|
112
|
+
unless ALLOWED_KEY_SIZES.include?(key_size)
|
113
|
+
raise 'Incorrect key size for AES'
|
114
|
+
end
|
115
|
+
|
116
|
+
cipher = ::OpenSSL::Cipher.new("AES-#{key_size}-CBC")
|
117
|
+
cipher.decrypt
|
118
|
+
cipher.key = key
|
119
|
+
cipher.iv = init_vector if init_vector.present?
|
120
|
+
Types::Binary.new(cipher.update(string) + cipher.final)
|
121
|
+
end
|
122
|
+
|
123
|
+
def pbkdf2_hmac_sha1(string, salt, iterations = 1000, key_len = 16)
|
124
|
+
Types::Binary.new(::OpenSSL::PKCS5.pbkdf2_hmac_sha1(string, salt, iterations, key_len))
|
125
|
+
end
|
126
|
+
|
127
|
+
def csv
|
128
|
+
@csv ||= CsvPackage.new
|
129
|
+
end
|
130
|
+
|
131
|
+
def stream
|
132
|
+
@stream ||= StreamPackage.new(streams: streams, connection: connection)
|
133
|
+
end
|
134
|
+
|
135
|
+
private
|
136
|
+
|
137
|
+
def method_missing(symbol, *_args)
|
138
|
+
raise UndefinedStdLibMethodError.new(symbol.to_s, 'workato')
|
139
|
+
end
|
140
|
+
|
141
|
+
def respond_to_missing?(*)
|
142
|
+
false
|
143
|
+
end
|
144
|
+
|
145
|
+
attr_reader :streams
|
146
|
+
|
147
|
+
attr_reader :connection
|
148
|
+
end
|
149
|
+
end
|
150
|
+
end
|
151
|
+
end
|
152
|
+
end
|
@@ -5,10 +5,11 @@ require_relative './block_invocation_refinements'
|
|
5
5
|
|
6
6
|
require_relative './dsl/http'
|
7
7
|
require_relative './dsl/call'
|
8
|
+
require_relative './dsl/reinvoke_after'
|
8
9
|
require_relative './dsl/error'
|
9
10
|
require_relative './dsl/account_property'
|
10
11
|
require_relative './dsl/lookup_table'
|
11
|
-
require_relative './dsl/
|
12
|
+
require_relative './dsl/workato_package'
|
12
13
|
require_relative './dsl/workato_schema'
|
13
14
|
require_relative './dsl/time'
|
14
15
|
require_relative './dsl/aws'
|
@@ -19,12 +20,31 @@ module Workato
|
|
19
20
|
module Sdk
|
20
21
|
module Dsl
|
21
22
|
module Global
|
23
|
+
extend T::Sig
|
24
|
+
extend T::Helpers
|
25
|
+
|
26
|
+
abstract!
|
27
|
+
|
28
|
+
# @api private
|
29
|
+
sig { abstract.returns(Streams) }
|
30
|
+
def streams; end
|
31
|
+
|
32
|
+
# @api private
|
33
|
+
sig { abstract.returns(Connection) }
|
34
|
+
def connection; end
|
35
|
+
|
22
36
|
include Time
|
23
37
|
include AccountProperty
|
24
38
|
include LookupTable
|
25
|
-
include WorkatoCodeLib
|
26
39
|
include WorkatoSchema
|
27
|
-
|
40
|
+
|
41
|
+
delegate :parse_json,
|
42
|
+
:uuid,
|
43
|
+
to: :workato
|
44
|
+
|
45
|
+
def workato
|
46
|
+
@workato ||= WorkatoPackage.new(streams: streams, connection: connection)
|
47
|
+
end
|
28
48
|
|
29
49
|
def sleep(seconds)
|
30
50
|
::Kernel.sleep(seconds.presence || 0)
|
@@ -33,6 +53,39 @@ module Workato
|
|
33
53
|
def puts(*args)
|
34
54
|
T.unsafe(::Kernel).puts(*args)
|
35
55
|
end
|
56
|
+
|
57
|
+
def encrypt(text, key)
|
58
|
+
::Kernel.require('ruby_rncryptor')
|
59
|
+
|
60
|
+
enc_text = ::RubyRNCryptor.encrypt(text, key)
|
61
|
+
::Base64.strict_encode64(enc_text)
|
62
|
+
end
|
63
|
+
|
64
|
+
def decrypt(text, key)
|
65
|
+
::Kernel.require('ruby_rncryptor')
|
66
|
+
|
67
|
+
text = ::Base64.decode64(text)
|
68
|
+
dec_text = ::RubyRNCryptor.decrypt(text, key)
|
69
|
+
Workato::Types::Binary.new(dec_text)
|
70
|
+
rescue Exception => e # rubocop:disable Lint/RescueException
|
71
|
+
message = e.message.to_s
|
72
|
+
case message
|
73
|
+
when /Password may be incorrect/
|
74
|
+
::Kernel.raise 'invalid/corrupt input or key'
|
75
|
+
when /RubyRNCryptor only decrypts version/
|
76
|
+
::Kernel.raise 'invalid/corrupt input'
|
77
|
+
else
|
78
|
+
::Kernel.raise
|
79
|
+
end
|
80
|
+
end
|
81
|
+
|
82
|
+
def blank; end
|
83
|
+
|
84
|
+
def clear; end
|
85
|
+
|
86
|
+
def null; end
|
87
|
+
|
88
|
+
def skip; end
|
36
89
|
end
|
37
90
|
|
38
91
|
class WithDsl
|
@@ -42,21 +95,23 @@ module Workato
|
|
42
95
|
|
43
96
|
using BlockInvocationRefinements
|
44
97
|
|
45
|
-
sig { params(connection: Connection,
|
46
|
-
def
|
98
|
+
sig { params(connection: Connection, streams: Streams).void }
|
99
|
+
def initialize(connection = Connection.new, streams = ProhibitedStreams.new)
|
47
100
|
@connection = connection
|
48
|
-
|
101
|
+
@streams = streams
|
49
102
|
end
|
50
103
|
|
51
|
-
|
52
|
-
|
53
|
-
T.unsafe(WithDsl.new).execute(connection, *args, &block)
|
104
|
+
def execute(...)
|
105
|
+
T.unsafe(self).instance_exec(...)
|
54
106
|
end
|
55
107
|
|
56
108
|
private
|
57
109
|
|
58
|
-
sig { returns(Connection) }
|
110
|
+
sig { override.returns(Connection) }
|
59
111
|
attr_reader :connection
|
112
|
+
|
113
|
+
sig { override.returns(Streams) }
|
114
|
+
attr_reader :streams
|
60
115
|
end
|
61
116
|
end
|
62
117
|
end
|